//
//  InsCcMusicTool.swift
//  ParsingCC
//
//  Created by insbridge-macmini1 on 2021/9/1.
//

import UIKit
import SwiftyJSON


class InsCcMusicModel: NSObject {
    
    var parts = [InsCcPartModel]();
    
    
    var title = "";
    
    var composer = "";
    
    
    func makeData(json : JSON , fileName : String , tempos : [JSON]) -> Bool {
        self.parts.removeAll();
        if let parts = json["parts"].array {
            guard let lines = json["lines"].array else { return false; }
            for (index, part) in parts.enumerated() {
                let partModel = InsCcPartModel();
                self.parts.append(partModel);
                
                if let xmlMeasures = part["measures"].array {
                    for i in 0..<xmlMeasures.count {
                        
                        let measure = InsCcMeasuresModel(json: xmlMeasures[i], measureDuration: (i > 0) ? partModel.measures[i - 1].measureDuration : 4, index: i, changeNoteFifths: (i > 0) ? partModel.measures[i - 1].changeNoteFifths : 0);
                        for line in lines {
                            let lineJson = line.dictionary?["lineStaves"]?.array?[index] ?? JSON();
                            let m1 = line.dictionary?["m1"]?.intValue ?? 0;
                            let m2 = line.dictionary?["m2"]?.intValue ?? 0;
                            if m1 <= measure.measureIndex && m2 > measure.measureIndex {
                                for stave in measure.staves {
                                    stave.firstClef = lineJson["clef"].dictionary?["\(stave.staveIndex)"]?.stringValue ?? "";
                                }
                            }
                        }
                        
                        measure.measureIndex = i + 1;
                       
                        if i > 0 {
                            let measure1 = partModel.measures[i - 1];
                            if measure1.nextClef.count != 0 {
                                for staff in measure.staves {
                                    if staff.staveIndex == measure1.nextStaff {
                                        staff.voices.first?.notes.first?.clef = measure1.nextClef;
                                    }
                                }
                            }
                            if measure1.slurStopx != 0 {
                                if measure1.slurStopx > measure.w {
                                    measure.slurStopx = measure1.slurStopx - measure.w;
                                    measure.slurStaff = measure1.slurStaff;
                                }else{
                                    a : for stave in measure.staves {
                                        if stave.staveIndex == measure1.slurStaff {
                                            var isAdd = false;
                                            for voice in stave.voices {
                                                for (i , note) in voice.notes.enumerated() {
                                                    if i < voice.notes.count - 1 {
                                                        if abs(note.x - measure1.slurStopx) < 15 {
                                                            note.slur = "stop";
                                                            isAdd = true;
                                                            break a;
                                                        }
                                                    }
                                                }
                                            }
                                            if !isAdd {
                                                stave.voices.last?.notes.last?.slur = "stop";
                                            }
                                        }
                                    }
                                }
                                
                            }
                            
                            if measure.measureIndex == 16 {
//                                print(111);
                            }
                            for stave1 in measure1.staves {
                                for voice1 in stave1.voices {
                                    if voice1.moreDirections.count > 0 {
                                         for direction in voice1.moreDirections {
                                             a : for stave in measure.staves {
                                                if stave.staveIndex == stave1.staveIndex {
                                                    if let directionMode = direction as? ShmNoteDirectionModel {
                                                        if let octaveShift = directionMode.octaveShift {
                                                            for voice in stave.voices {
                                                                for note in voice.notes {
                                                                    if note.x <= direction.x {
                                                                        var step = 6 + note.line;
                                                                        var octave = 4;
                                                                        while !(step >= 0 && step < 7) {
                                                                            if step >= 7 {
                                                                                step -= 7
                                                                                octave += 1;
                                                                            }else if step <= 0 {
                                                                                step += 7;
                                                                                octave -= 1;
                                                                            }
                                                                        }
                                                                        note.octave = octave;
                                                                        note.step = step;
                                                                        if octaveShift.isUp {
                                                                            note.octave -= (octaveShift.shiftSize/8);
                                                                        }else{
                                                                            note.octave += (octaveShift.shiftSize/8);
                                                                        }
                                                                    }
                                                                }
                                                            }
                                                        }
                                                    }
                                                    for voice in stave.voices {
                                                        if voice.voiceIndex == voice1.voiceIndex {
                                                            if direction.x > measure.w {
                                                                direction.x -= measure.w;
                                                                voice.moreDirections.append(direction);
                                                            }else{
                                                                voice.directions.append(direction);
                                                            }
                                                            break a;
                                                        }
                                                    }
                                                }
                                            }
                                        }
                                    }
                                }
                            }
                        }
                        partModel.measures.append(measure);
                    }
                    
                    var number = 0;
                    for measures in partModel.measures {
                        var array = [ShmOctaveShiftModel]();
                        for staff in measures.staves {
                            for v in staff.voices {
                                for d in v.directions {
                                    if let direction = d as? ShmNoteDirectionModel {
                                        if let octaveShift = direction.octaveShift {
                                            array.append(octaveShift);
                                        }
                                    }
                                }
                            }
                        }
                   
                        for (i , (shift1 , shift2)) in measures.shiftArray.enumerated() {
                            shift1.number = "\(i + 1 + number)";
                            shift2.number = "\(i + 1 + number)";
                        }
                        
                        if array.count != 0 {
                            for shift in array {
                                if shift.type == "stop" {
                                    number -= 1;
                                }else{
                                    number += 1;
                                }
                            }
                        }
                    }
                    
                    number = 0;
                    for measures in partModel.measures {
                        var array = [ShmWedgeModel]();
                        for staff in measures.staves {
                            for v in staff.voices {
                                for d in v.directions {
                                    if let direction = d as? ShmNoteDirectionModel {
                                        if let octaveShift = direction.wedge {
                                            array.append(octaveShift);
                                        }
                                    }
                                }
                            }
                        }
                        for (i , (shift1 , shift2)) in measures.wedgeArray.enumerated() {
                            shift1.number = "\(i + 1 + number)";
                            shift2.number = "\(i + 1 + number)";
                        }
                        
                        if array.count != 0 {
                            for shift in array {
                                if shift.type == "stop" {
                                    number -= 1;
                                }else{
                                    number += 1;
                                }
                            }
                        }
                    }
                }
                
                if let measure = partModel.measures.first {
                    var maxDuration = 0.0;
                    for stave in measure.staves {
                        var duration = 0.0;
                        for v in stave.voices {
                            if !(v.notes.count == 1 && (v.notes.first?.rest ?? false)) {
                                for note in v.notes {
                                    duration += note.duration;
                                }
                                break;
                            }
                        }
                        if maxDuration < duration {
                            maxDuration = duration;
                        }
                    }
                    measure.measureDuration = maxDuration;
                }
            }
            
        }
        
        var firstMeasureDuration = 0.0;
        for partModel in self.parts {
            if let measure = partModel.measures.first {
                if firstMeasureDuration < measure.measureDuration {
                    firstMeasureDuration = measure.measureDuration;
                }
            }
        }
        
        for partModel in self.parts {
            if let measure = partModel.measures.first {
                measure.measureDuration = firstMeasureDuration;
                for stave in measure.staves {
                    for v in stave.voices {
                        if let lastNote = v.notes.last {
                            if Double(lastNote.tick)/480.0 + lastNote.duration > measure.measureDuration {
                                if Double(lastNote.tick)/480.0 < measure.measureDuration {
                                    lastNote.duration = measure.measureDuration - Double(lastNote.tick)/480.0;
                                }
                            }
                        }
                    }
                }
                for (j , stave) in measure.staves.enumerated() {
                    for (h , v) in stave.voices.enumerated() {
                        for (i , note) in v.notes.reversed().enumerated() {
                            if i == 0 {
                                note.tick = Int((measure.measureDuration - note.duration) * 480);
                            }else {
                                note.tick = v.notes[v.notes.count - 1 - i + 1].tick - Int(note.duration * 480);
                            }
                        }
                        if let note = v.notes.first {
                            if note.tick > 0 {
                                var duration = Double(note.tick) / 480;
                                var count = 0;
                                var tick = 0;
                                while duration > 0 {
                                    let restNote = InsCcNote(json: JSON());
                                    restNote.staff = note.staff;
                                    restNote.v = note.v;
                                    restNote.tick = tick;
                                    restNote.rest = true;
                                    if duration >= 4 {
                                        restNote.type = 1;
                                        duration -= 4;
                                    }else if duration >= 2 {
                                        restNote.type = 2;
                                        duration -= 2;
                                    }else if duration >= 1 {
                                        restNote.type = 4;
                                        duration -= 1;
                                    }else if duration >= 0.5 {
                                        restNote.type = 8;
                                        duration -= 0.5;
                                    }else if duration >= 0.25 {
                                        restNote.type = 16;
                                        duration -= 0.25;
                                    }else if duration >= 0.125 {
                                        restNote.type = 32;
                                        duration -= 0.125;
                                    }else{
                                        restNote.type = 64;
                                        duration -= 0.0625;
                                    }
                                    restNote.duration = 4.0/Double(restNote.type);
                                    tick += Int(restNote.duration) * 480;
                                    if note.clef.count != 0 {
                                        restNote.clef = note.clef;
                                        note.clef = "";
                                    }
                                    v.notes.insert(restNote, at: count);
                                    count += 1;
                                }
                                
                            }
                        }
                    }
                }
            }
        }
        
        for part in parts {
            for (i , m) in part.measures.enumerated() {
//                if m.endM1 != 0 && m.location == "right" && m.endM1 == m.measureIndex && m.endM1 != m.endM2 {
//                    if i + 1 < part.measures.count - 1 {
//                        part.measures[i + 1].endM1 = m.endM1 + 1;
//                        part.measures[i + 1].endM2 = m.endM2;
//                        part.measures[i + 1].endNumber = m.endNumber;
//                        part.measures[i + 1].location = "left";
//                        part.measures[i + 1].barStyle = m.barStyle;
//                        m.barStyle = "";
//                        m.endM1 = 0;
//                        m.endM2 = 0;
//                        m.location = "";
//                        continue;
//                    }
//                }
                if m.endM2 != 0 {
                    for j in (i+1)..<part.measures.count {
                        let m2 = part.measures[j];
                        if m2.measureIndex == m.endM2 {
                            m2.endM1 = m.endM1;
                            m2.endM2 = m.endM2;
                            m2.endNumber = m.endNumber;
                            break;
                        }
                    }
                }
            }
        }
        
        if self.parts.count == 2 {
            var array = [Int]();
            for part in parts {
                var arr = [Int]();
                for m in part.measures {
                    for staff in m.staves {
                        if !arr.contains(staff.staveIndex) {
                            arr.append(staff.staveIndex);
                        }
                    }
                }
                array.append(arr.count);
            }
            if array.count == 2 && array[0] == 1 && array[1] == 1 {
                for (i , measures) in self.parts[0].measures.enumerated() {
                    if i < self.parts[1].measures.count {
                        let measure1 = self.parts[1].measures[i];
                        if measure1.staves.count > 0 {
                            let staff2 = measure1.staves[0];
                            staff2.staveIndex = 2;
                            measures.staves.append(staff2);
                        }
                    }
                }
                self.parts.removeLast();
            }
           
        }
        
//        a : for json in tempos {
//            let tick = json["tick"].doubleValue/480.0;
//            let tempo = json["tempo"].doubleValue/10000.0;
//            var allMeasureDuration = 0.0;
//            for (i , measure) in self.parts[0].measures.enumerated() {
//                if allMeasureDuration <= tick && tick <= allMeasureDuration + measure.measureDuration {
//                    for stave in measure.staves {
//                        for voice in stave.voices {
//                            for note in voice.notes {
//                                if fabs(Double(note.tick)/480 - (tick - allMeasureDuration)) < 0.06 {
//                                    note.metronome = "\(Int(round(tempo)))";
//                                    continue a;
//                                }
//                            }
//                        }
//                    }
//                }
//                allMeasureDuration += measure.measureDuration;
//            }
//        }
        
        if let title = json["title"].dictionary?["title"]?.string{
            self.title = title;
        }
        
        let xml = ShmMusicXmlModel();
        xml.nodeName = "score-partwise"
        xml.version = "3.0";
        xml.musicName = self.title;
        xml.identification = ShmIdentificationModel();
        let partList = ShmPartListModel();
        for i in 0..<self.parts.count {
            let partgroupModel1 = ShmPartgroupModel();
            partgroupModel1.number = "\(i + 1)";
            partgroupModel1.groupSymbol = "brace";
            partgroupModel1.type = "start";
            partList.partgroups.append(partgroupModel1);
            
            let partgroupModel2 = ShmPartgroupModel();
            partgroupModel2.number = "\(i + 1)";
            partgroupModel2.type = "stop";
            partList.partgroups.append(partgroupModel2);
            
            let scoreModel = ShmScorePartModel();
            scoreModel.id = "P\(i + 1)"
            scoreModel.scoreInstrument.id = "P\(i + 1)-l1"
            partList.scorePart.append(scoreModel);
        }
        
        
        xml.partList = partList;
        
        for i in 0..<self.parts.count {
            let pratModel = ShmPartModel();
            pratModel.id = "P\(i + 1)";
            xml.parts.append(pratModel);
            
            for (j , measure) in self.parts[i].measures.enumerated() {
                //                if j > 100 {
                //                    break;
                //                }
//                if j == 4 {
//                    break;
//                }
                let measureModel = ShmMeasureModel();
                measureModel.number = "\(j + 1)";
                measureModel.width = "309";
                measureModel.print = ShmMeasurePrintModel();
                if measure.measureIndex % 20 == 39 {
                    measureModel.print?.newPage = true;
                }
                
                pratModel.measures.append(measureModel);
                
                if j == 0 {
                    
                    let staffLayout = ShmMeasureStaffLayoutModel();
                    staffLayout.number = "2";
                    staffLayout.staffDistance = "55";
                    measureModel.print?.staffLayout = staffLayout;
                    
                    let attributesModel = ShmMeasureAttributesModel();
                    attributesModel.divisions = "256";
                    
                    attributesModel.staves = "\(measure.staves.count)";
                    
                    if j == 0 {

                        if attributesModel.clefs.count == 0 {
                            for (i , staff) in measure.staves.enumerated() {
                                let clef = ShmMeasureClefsModel();
                                clef.color = "#000000"
                                clef.number = "\(i + 1)";
                                if staff.firstClef.contains("Bass") {
                                    clef.sign = "F";
                                    clef.line = "4";
                                }else {
                                    clef.sign = "G";
                                    clef.line = "2";
                                }
                                if staff.firstClef.contains("8va") {
                                    clef.clefOctaveChange = 1;
                                }else if staff.firstClef.contains("8vb") {
                                    clef.clefOctaveChange = -1;
                                }
                                attributesModel.clefs.append(clef);
                            }
                        }
                        
                        attributesModel.key = ShmMeasureKeyModel();
                        attributesModel.key?.color = "#000000"
                        attributesModel.key?.fifths = "\(measure.fifths)"
                        attributesModel.key?.mode = "major";
                        
//                        measure.fifths = 0;
                        
                        attributesModel.time = ShmMeasureTimesModel();
                        attributesModel.time?.color = "#000000"
                        attributesModel.time?.beats = "\(measure.beats)"
                        attributesModel.time?.beatType = "\(measure.beatType)";
//                        measure.beats = 0;
//                        measure.beatType = 0;
                    }
                    
                    let staffDetails = ShmMeasureStaffDetailsModel();
                    staffDetails.printObject = "yes";
                    staffDetails.number = "\(i + 1)";
                    attributesModel.staffDetails.append(staffDetails);
                    measureModel.attributes = attributesModel;
                }
                
                if  (measure.fifths != 0 || measure.cancel) || (measure.beatType != 0 && measure.beats != 0){
                    let attributesModel = ShmMeasureAttributesModel();
                    if (measure.fifths != 0 || measure.cancel) {
                        attributesModel.key = ShmMeasureKeyModel();
                        attributesModel.key?.color = "#000000"
                        attributesModel.key?.fifths = "\(measure.fifths)"
                        attributesModel.key?.mode = "major";
                    }
                    measureModel.notes.append(attributesModel);
                    if measure.beatType != 0 && measure.beats != 0 {
                        attributesModel.time = ShmMeasureTimesModel();
                        attributesModel.time?.color = "#000000"
                        attributesModel.time?.beats = "\(measure.beats)"
                        attributesModel.time?.beatType = "\(measure.beatType)";
                    }
                }
                
                if measure.location == "left" || measure.endM1 == measure.measureIndex {
                    let barlineModel = ShmBarlineModel();
                    barlineModel.location = "left";
                    if measure.location == "left" {
                        barlineModel.barStyle = measure.barStyle;
                        barlineModel.direction = measure.direction;
                    }
                    measureModel.notes.append(barlineModel);
                    if measure.endNumber.count != 0{
                        barlineModel.endingNumber = measure.endNumber;
                        if measure.measureIndex == measure.endM1 {
                            barlineModel.endingType = "start";
                        }else if measure.measureIndex == measure.endM2 {
                            barlineModel.endingType = "stop";
                        }
                    }
                }
                
                
                
                
                
                
                if measure.segnoType == 1 {
                    let soundModel = ShmNoteDirectionModel();
                    soundModel.staff = "\(measure.segnoStaff)";
                    soundModel.voice = "1";
                    soundModel.segno = true;
                    soundModel.sound = ShmSegnoModel();
                    soundModel.sound?.segno = "segno";
                    measureModel.notes.append(soundModel);
                }else if measure.segnoType == 3 {
                    let soundModel = ShmNoteDirectionModel();
                    soundModel.staff = "\(measure.segnoStaff)";
                    soundModel.voice = "1";
                    soundModel.sound = ShmSegnoModel();
                    soundModel.sound?.tocoda = "37";
                    soundModel.sound?.timeOnly = "2";
                    soundModel.sound?.offset = "1";
                    soundModel.offset = ShmOffsetModel();
                    soundModel.offset?.sound = "no";
                    soundModel.offset?.value = "255";
                    soundModel.words = ShmWordsModel();
                    soundModel.words?.text = "To coda"
                    measureModel.notes.append(soundModel);
                }else if measure.segnoType == 4 {
                    let soundModel = ShmNoteDirectionModel();
                    soundModel.staff = "\(measure.segnoStaff)";
                    soundModel.voice = "1";
                    soundModel.words = ShmWordsModel();
                    soundModel.words?.text = "Coda";
                    measureModel.notes.append(soundModel);
                }
                
                if measure.measureIndex == 31 {
                    print(11);
                }
                for (k , voice) in measure.voices.enumerated() {
                    var directions = [ShmBaseNoteModel]();
//                        directions.append(contentsOf: voice.directions);
                    for ccNote in voice.notes {
                        if ccNote.hide {
                            continue;
                        }
                        
//                            if ccNote.clef.count != 0 {
//                                let clef = ShmMeasureClefsModel();
//                                clef.x = ccNote.x - 1;
//                                clef.color = "#000000"
//                                clef.number = "\(stave.staveIndex)";
//                                if ccNote.clef == "Bass" {
//                                    clef.sign = "F";
//                                    clef.line = "4";
//                                }else {
//                                    clef.sign = "G";
//                                    clef.line = "2";
//                                }
//                                directions.append(clef);
//                            }
                        let note = ShmNoteModel();
                        note.x = ccNote.x;
                        note.color = "#000000"
                        note.defaultx = "88";
                        note.defaulty = "15";
                        if !ccNote.rest && ccNote.step > 0 {
                            note.pitch = ShmNotePitchModel();
                            note.pitch?.alter = ccNote.alter;
                            note.pitch?.octave = "\(ccNote.octave)";
                            let notes = ["C","D","E","F","G","A","B"];
                            note.pitch?.step = notes[ccNote.step];
                        }
                        note.duration = "\(Int(ccNote.duration * 256))";
                        note.rest = ccNote.rest;
                        note.arpeggiate = ccNote.arpeggiate;
                        note.glissando = ccNote.isGlissandoStart ? "start" : (ccNote.isGlissandoStop ? "stop" : "");
                        note.fermata = ccNote.fermata;
                        note.accent = ccNote.accent;
                        note.detachedLegato = ccNote.detachedLegato;
                        note.instrumentid = "P1-I1";
                        note.voice = "\(ccNote.v)";
                        note.dots = ccNote.dots;
                        note.accidental = ccNote.accidental;
//                            if ccNote.id == "n_1_14_8" {
//                                print(111);
//                            }
                        let typeNames = ["breve","whole","half","quarter","eighth","16th","32nd","64th"];
                        let typeValues = [0,1,2,4,8,16,32,64];
                        if let index = typeValues.firstIndex(of: ccNote.type) {
                            note.type = typeNames[index];
                        }
                        note.stem = ccNote.stemType;
                        note.tenuto = ccNote.tenuto;
                        note.staff = "\(ccNote.staff)";
                        note.tremolo = ccNote.tremolo;
                        note.tremoloType = ccNote.tremoloType;
                        note.wavyLine = ccNote.wavyLine;
                        note.trillmark = ccNote.trillmark;
                        note.turn = ccNote.isTurn;
                        if ccNote.trillmark {
//                            print(111);
                        }
                        note.slideStart = ccNote.isSlideStart;
                        note.slideStop = ccNote.isSlideStop;
                        note.articulations = ccNote.articulations;
                        note.invertedMordent = ccNote.invertedMordent;
                        note.slur = ccNote.slur;
                        note.slurNumber = "\(ccNote.staff)";
                        if ccNote.inbeam && ccNote.beamType.count != 0 {
                            let beamTypeArr = ["begin","continue","end"];
                            for (num, beam , _) in ccNote.beamType {
                                note.beam.append((num, beamTypeArr[beam]));
                            }
                        }
                        var tieds = [String]();
                        if ccNote.tiedStart.count != 0 {
                            tieds.append(ccNote.tiedStart);
                        }
                        if ccNote.tiedStop.count != 0 {
                            tieds.append(ccNote.tiedStop);
                        }
                        note.tieds = tieds;
                        if ccNote.id == "n_41_2" {
//                                print(111);
                        }
                        if ccNote.clef.count != 0 {
                            note.clef = ccNote.clef;
                            let attributesModel = ShmMeasureAttributesModel();
                            let clef = ShmMeasureClefsModel();
                            attributesModel.x = ccNote.x;
                            clef.color = "#000000"
                            clef.number = "\(ccNote.staff)";
                            if note.clef.contains("Bass") {
                                clef.sign = "F";
                                clef.line = "4";
                            }else {
                                clef.sign = "G";
                                clef.line = "2";
                            }
                            if note.clef.contains("8va") {
                                clef.clefOctaveChange = 1;
                            }else if note.clef.contains("8vb") {
                                clef.clefOctaveChange = -1;
                            }
                            attributesModel.clefs.append(clef);
                            directions.append(attributesModel);
                        }
                        note.isGraceSlash = ccNote.isGraceSlash;
                        if ccNote.tuplet != 0 {
                            note.timeModification = ShmTimeModificationModel();
                            note.timeModification?.actualNotes = ccNote.tuplet;
                            note.timeModification?.normalType = note.type ?? "";
                            note.timeModification?.normalNotes = ccNote.normalNotes;
//                                print("ddddd" , ccNote.tuplet, ccNote.normalNotes)
                        }
                        if ccNote.isTupletStop || ccNote.isTupletStart {
                            note.tuplet = ShmTupletModel();
                            if ccNote.isTupletStart {
                                note.tuplet?.type = "start";
                            }else{
                                note.tuplet?.type = "stop";
                            }
                            if ccNote.isTupletUp {
                                note.tuplet?.placement = "above";
                            }else{
                                note.tuplet?.placement = "below";
                            }
                           
                        }
                        if ccNote.isPedal {
                            let direction = ShmNoteDirectionModel();
                            direction.pedal = ccNote.pedalType;
                            direction.voice = "\(voice.voiceIndex + 1)";
                            direction.staff = "\(ccNote.staff)";
                            directions.append(direction);
                        }
                        if ccNote.metronome.count != 0 {
                            let metronomeModel = ShmNoteDirectionModel();
                            metronomeModel.x = ccNote.x;
                            metronomeModel.staff = note.staff;
                            metronomeModel.voice = note.voice;
                            metronomeModel.metronome = ShmMetronomeModel();
                            metronomeModel.metronome?.perMinute = ccNote.metronome;
                            directions.append(metronomeModel);
                        }
                        
                        if ccNote.dynString.count != 0 {
                            let dynamicsModel = ShmNoteDirectionModel();
                            dynamicsModel.x = ccNote.x;
                            dynamicsModel.staff = note.staff;
                            dynamicsModel.voice = note.voice;
                            dynamicsModel.dynamics = ShmDynamicsModel();
                            dynamicsModel.dynamics?.dynamics = ccNote.dynString;
                            directions.append(dynamicsModel);
                        }
                        
                        if ccNote.fingeringArray.count > 0 {
                            for str in ccNote.fingeringArray {
                                let soundModel = ShmNoteDirectionModel();
                                soundModel.x = ccNote.x;
                                soundModel.staff = "\(ccNote.staff)";
                                soundModel.voice = "\(voice.voiceIndex + 1)";
                                soundModel.words = ShmWordsModel();
                                soundModel.words?.text = str;
                                soundModel.words?.fontSize = "6";
                                directions.append(soundModel);
                            }
                        }
                        
                        if ccNote.lyrics.count != 0 {
                            note.lyric = ShmLyricModel();
                            note.lyric?.text = ccNote.lyrics[0].0;
                            note.lyric?.defaulty = Int(ccNote.lyrics[0].1);
                        }
                     
                        if ccNote.word.count != 0 {
                            let wordModel = ShmNoteDirectionModel();
                            wordModel.x = note.x;
                            wordModel.staff = "\(ccNote.staff)";
                            wordModel.voice = "\(voice.voiceIndex + 1)";
                            wordModel.words = ShmWordsModel();
                            wordModel.words?.text = ccNote.word
                            directions.append(wordModel);
                        }
                        directions.append(note);
                       
                        for ccChordNote in ccNote.chordNotes {
                            let note = ShmNoteModel();
                            note.x = ccNote.x;
                            note.chord = true;
                            note.color = "#000000"
                            note.defaultx = "88";
                            note.defaulty = "15";
                            note.pitch = ShmNotePitchModel();
                            note.pitch?.alter = ccChordNote.alter;
                            note.pitch?.octave = "\(ccChordNote.octave)";
                            let notes = ["C","D","E","F","G","A","B"];
                            if ccChordNote.step > 0 {
                                note.pitch?.step = notes[ccChordNote.step];
                            }
                            
                            note.duration = "\(Int(ccNote.duration * 256))";
                            note.rest = ccNote.rest;
                            note.instrumentid = "P1-I1";
                            note.isGraceSlash = ccNote.isGraceSlash;
                            note.accidental = ccChordNote.accidental;
                            note.arpeggiate = ccNote.arpeggiate;
                            note.invertedMordent = ccNote.invertedMordent;
                            let typeNames = ["whole","half","quarter","eighth","16th","32nd"];
                            let typeValues = [1,2,4,8,16,32];
                            if let index = typeValues.firstIndex(of: ccNote.type) {
                                note.type = typeNames[index];
                            }
                            note.stem = ccNote.stemType;
                            note.staff = "\(ccNote.staff)";
                            note.dots = ccNote.dots;
                            note.tremolo = ccNote.tremolo;
                            note.tremoloType = ccNote.tremoloType;
                            note.wavyLine = ccNote.wavyLine;
                            note.trillmark = ccNote.trillmark;
                            note.turn = ccNote.isTurn;
                            var tieds = [String]();
                            if ccChordNote.tiedStart.count != 0 {
                                tieds.append(ccChordNote.tiedStart);
                            }
                            if ccChordNote.tiedStop.count != 0 {
                                tieds.append(ccChordNote.tiedStop);
                            }
                            if ccNote.tuplet != 0 {
                                note.timeModification = ShmTimeModificationModel();
                                note.timeModification?.actualNotes = ccNote.tuplet;
                                note.timeModification?.normalType = note.type ?? "";
                                note.timeModification?.normalNotes = ccNote.normalNotes;
//                                    print("ddddd" , ccNote.tuplet, ccNote.normalNotes)
                            }
                            note.tieds = tieds;
                            directions.append(note);
                        }
                    }
                    if measure.measureIndex == 31 {
                            print(11);
                    }
                    
//                        for direction in voice.directions {
//                            for (i , model) in directions.enumerated() {
//                               if model.x < direction.x && i == directions.count - 1 {
//                                    directions.append(direction);
//                                    break;
//                                }else{
//                                    if i == 0 {
//                                        if model.x >= direction.x{
//                                            directions.insert(direction, at: 0);
//                                            break;
//                                        }
//                                    }else{
//                                        if model.x >= direction.x && directions[i - 1].x < direction.x {
//                                            directions.insert(direction, at: i);
//                                            break;
//                                        }
//                                    }
//                                }
//                            }
//                        }
                    directions.append(contentsOf: voice.directions);
                    directions = directions.sorted(by: { model1, model2 in
                        return model1.x < model2.x;
                    });
                    measureModel.notes.append(contentsOf: directions);
                    
                    if k == 0 && (measure.location == "right" || measure.measureIndex == measure.endM2){
                        let barlineModel = ShmBarlineModel();
                        barlineModel.location = "right";
                        if measure.location == "right" {
                            barlineModel.barStyle = measure.barStyle;
                            barlineModel.direction = measure.direction;
                        }
                        measureModel.notes.append(barlineModel);
                        if measure.endNumber.count != 0 {
                            barlineModel.endingNumber = measure.endNumber;
                            if measure.measureIndex == measure.endM1 {
                                barlineModel.endingType = "start";
                            }
                            if measure.measureIndex == measure.endM2 {
                                barlineModel.endingType = "stop";
                            }
                        }
                    }
                    if k == 0 && measure.segnoType == 2 {
                        let soundModel = ShmNoteDirectionModel();
                        soundModel.staff = "\(measure.segnoStaff)";
                        soundModel.voice = "1";
                        soundModel.sound = ShmSegnoModel();
                        soundModel.sound?.dalsegno = "2";
                        soundModel.sound?.offset = "1";
                        soundModel.offset = ShmOffsetModel();
                        soundModel.offset?.sound = "no";
                        soundModel.offset?.value = "255";
                        soundModel.words = ShmWordsModel();
                        soundModel.words?.text = "D.S. al Coda"
                        measureModel.notes.append(soundModel);
                    }
                    if !(k == measure.voices.count - 1) {
                        let backupModel = ShmBackUpModel();
                        backupModel.duration = Int(measure.measureDuration * 256);
                        measureModel.notes.append(backupModel);
                    }
                   
                }
            }
        }
        
        xml.getXmlString(fileName: fileName);
        return true;
    }
    
    
}


